<?php

require_once DCES_BASE_DIR . 'utils/Problem.php';
require_once DCES_BASE_DIR . 'utils/ServerPlugin.php';

function getSetting($contest_setting, $problem_setting) {
    return is_null($problem_setting) ? $contest_setting : $problem_setting;
}

function processSubmitSolutionRequest(SubmitSolutionRequest $request) {
    $prfx = DB_PREFIX;

    //get user_id or die, if session is invalid
    $userRow = RequestUtils::testSession($request->sessionID);
    $user_id = $userRow['id'];

    //authorize user for this operation
    // get contest ID
    $user_type = $userRow['user_type'];

    //get problem row
    $problem_row = Data::getRow(
        sprintf("SELECT * FROM ${prfx}problem WHERE id=%s", Data::quote_smart($request->problemID))
    );
    if (!$problem_row)
        throwBusinessLogicError(4);

    //get contest id of a problem
    $problem_contest_id = $problem_row['contest_id'];

    //test if we have rights to submit solution for the contest
    $contest_id = RequestUtils::getRequestedContest($problem_contest_id, $userRow['contest_id'], $user_type);

    if ($contest_id < 0)
        throwBusinessLogicError(0);

    //get all settings
    /** @var $contest_settings ContestDescription */
    $contest_settings = Data::_unserialize($userRow['settings']);

    //test submission time

    $cur_time = getCurrentContestTime(
        $contest_settings,
        DateMySQLToPHP($userRow['contest_start']),
        DateMySQLToPHP($userRow['contest_finish'])
    );

    if ($cur_time['interval'] === 'before')
        throwBusinessLogicError(19);
    if ($cur_time['interval'] === 'after')
        throwBusinessLogicError(20);

    //test that not all submission attempts were used    
    $hist = Data::getRow(
        sprintf(
            "SELECT COUNT(*) AS cnt FROM ${prfx}submission_history WHERE (problem_id=%s) AND (user_id=%s)",
            Data::quote_smart($request->problemID),
            Data::quote_smart($user_id)
        )
    );

    //get problem settings
    /** @var $problem_settings ContestSpecificSettings */
    $problem_settings = Data::_unserialize($problem_row['contest_settings']);
    if (!$problem_settings)
        $problem_settings = $contest_settings->problemsDefaultSettings;

    if ($hist['cnt'] >= $problem_settings->sendCount)
        throwBusinessLogicError(21);

    //get problem and create plugin
    $problem = new Problem(getProblemFile($request->problemID));
    $plugin_alias = $problem->getServerPlugin();
    require_once(getServerPluginFile($plugin_alias));
    /** @var $plugin ServerPlugin */
    $plugin = new $plugin_alias($problem);

    //save submission result in history
    $cur_php_time = getdate();
    $unique_id = Data::getUniqueId();

    $col_value = array();

    $result = $plugin->checkSolution($request->problemResult, $unique_id);

    $col_value['id'] = $unique_id;
    $col_value['problem_id'] = $request->problemID;
    $col_value['user_id'] = $user_id;
    $col_value['contest_id'] = $contest_id;
    $col_value['submission'] = serialize($request->problemResult);
    $col_value['submission_time'] = DatePHPToMySQL($cur_php_time[0]);

    if ($result) {
        $col_value['result'] = serialize($result);
        $col_value['test_id'] = $unique_id;
        $col_value['test_time'] = $col_value['submission_time'];
    } else {
        $col_value['result'] = null;
        $col_value['test_id'] = null;
        $col_value['test_time'] = null;
    }

    Data::submitModificationQuery(Data::composeInsertQuery('submission_history', $col_value));

    //return submission result
    $res = new SubmitSolutionResponse();

    $res->submissionId = $unique_id;

    return $res;
}

?>